package controller.game.player;

import entity.CounterMessage;
import entity.Message;
import entity.ServerMessage;
import entity.evaluation.EvaluatorHelper;

import java.util.List;

public abstract class Player implements Playable{

    protected int roomNum;
    protected int playerNum;
    protected Type type;
    protected EvaluatorHelper helper;
    private Object senderLock;
    protected CounterMessage lastCounterMessage;

    public Player(){}

    public Player(int roomNum, int playerNum, EvaluatorHelper helper){
        initPlayer(roomNum, playerNum, helper);
    }

    public void initPlayer(int roomNum, int playerNum, EvaluatorHelper helper){
        this.roomNum = roomNum;
        this.playerNum = playerNum;
        this.helper = helper;
        this.senderLock = new Object();
    }

    private void unlockSender(){
        synchronized (senderLock){
            senderLock.notify();
        }
    }

    private void lockSender(){
        synchronized (senderLock){
            try {
                senderLock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onReceive(Message message){
        if(message instanceof CounterMessage){
            CounterMessage counterMessage = (CounterMessage) message;
            this.lastCounterMessage = counterMessage;
            List<Integer> speakers = counterMessage.getSpeakers();
            if(speakers.contains(this.playerNum)){
                this.unlockSender();
            }
        }else if(message instanceof ServerMessage){
            ServerMessage serverMessage = (ServerMessage) message;
            switch (serverMessage.getEvent()){
                case Client_Disconnect:
                    break;
                case Nego_Interrupt:
                    break;
                case Nego_Start:
                    if(this.playerNum == 0){
                        this.unlockSender();
                    }
                    break;
                case Nego_Resume:
                    if(lastCounterMessage!=null){
                        if(lastCounterMessage.getSpeakers().contains(this.playerNum))
                            this.unlockSender();
                    }else{
                        if(this.playerNum == 0)
                            this.unlockSender();
                    }
                    break;
                case Nego_Finished:
                    break;
            }
        }
        receiveMessage(message);
    }

    @Override
    public CounterMessage getMessage(){
        this.lockSender();
        return sendMessage();
    }

    public abstract void receiveMessage(Message message);

    public abstract CounterMessage sendMessage();

}
